package com.cardcaptorsakura.security;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 内容安全过滤服务
 * 提供对用户输入和AI输出内容的安全检查功能
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ContentFilterService {

    @Value("${app.content.filter.enabled:true}")
    private boolean contentFilterEnabled;

    @Value("${app.content.filter.strict-mode:false}")
    private boolean strictMode;

    @Value("${app.content.filter.auto-replace:true}")
    private boolean autoReplace;

    // 敏感词库
    private static final Set<String> SENSITIVE_WORDS = new HashSet<>(Arrays.asList(
        // 政治敏感词
        "政治敏感词1", "政治敏感词2",
        // 暴力相关
        "暴力", "杀害", "伤害", "攻击",
        // 色情相关
        "色情", "成人内容",
        // 歧视相关
        "种族歧视", "性别歧视",
        // 其他不当内容
        "欺诈", "诈骗", "违法"
    ));

    // 医疗免责声明关键词
    private static final Set<String> MEDICAL_KEYWORDS = new HashSet<>(Arrays.asList(
        "诊断", "治疗", "药物", "病症", "疾病", "医生", "医院", "手术", "药品", "处方",
        "症状", "病情", "医疗", "健康", "疼痛", "发烧", "感染", "癌症", "肿瘤"
    ));

    // 法律免责声明关键词
    private static final Set<String> LEGAL_KEYWORDS = new HashSet<>(Arrays.asList(
        "法律", "律师", "起诉", "诉讼", "合同", "法院", "判决", "法规", "条例", "违法",
        "犯罪", "刑事", "民事", "行政", "仲裁", "调解", "赔偿", "责任", "权利", "义务"
    ));

    // 金融投资免责声明关键词
    private static final Set<String> FINANCIAL_KEYWORDS = new HashSet<>(Arrays.asList(
        "投资", "股票", "基金", "理财", "贷款", "信贷", "保险", "银行", "金融", "证券",
        "期货", "外汇", "债券", "风险", "收益", "利率", "汇率", "财务", "资产", "负债"
    ));

    // 正则表达式模式
    private static final Pattern PHONE_PATTERN = Pattern.compile("\\b1[3-9]\\d{9}\\b");
    private static final Pattern EMAIL_PATTERN = Pattern.compile("\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b");
    private static final Pattern ID_CARD_PATTERN = Pattern.compile("\\b\\d{15}|\\d{18}\\b");
    private static final Pattern BANK_CARD_PATTERN = Pattern.compile("\\b\\d{16,19}\\b");
    private static final Pattern URL_PATTERN = Pattern.compile("https?://[\\w\\-._~:/?#\\[\\]@!$&'()*+,;=%]+");

    /**
     * 内容过滤结果
     */
    public static class FilterResult {
        private boolean safe;
        private String filteredContent;
        private List<String> violations;
        private List<String> warnings;
        private String riskLevel;
        private Map<String, Object> metadata;

        public FilterResult() {
            this.violations = new ArrayList<>();
            this.warnings = new ArrayList<>();
            this.metadata = new HashMap<>();
        }

        // Getters and Setters
        public boolean isSafe() { return safe; }
        public void setSafe(boolean safe) { this.safe = safe; }
        public String getFilteredContent() { return filteredContent; }
        public void setFilteredContent(String filteredContent) { this.filteredContent = filteredContent; }
        public List<String> getViolations() { return violations; }
        public void setViolations(List<String> violations) { this.violations = violations; }
        public List<String> getWarnings() { return warnings; }
        public void setWarnings(List<String> warnings) { this.warnings = warnings; }
        public String getRiskLevel() { return riskLevel; }
        public void setRiskLevel(String riskLevel) { this.riskLevel = riskLevel; }
        public Map<String, Object> getMetadata() { return metadata; }
        public void setMetadata(Map<String, Object> metadata) { this.metadata = metadata; }
    }

    /**
     * 过滤用户输入内容
     */
    public FilterResult filterUserInput(String content, String userId) {
        if (!contentFilterEnabled) {
            FilterResult result = new FilterResult();
            result.setSafe(true);
            result.setFilteredContent(content);
            result.setRiskLevel("LOW");
            return result;
        }

        try {
            FilterResult result = new FilterResult();
            String filteredContent = content;
            
            // 1. 检查敏感词
            FilterResult sensitiveWordResult = checkSensitiveWords(filteredContent);
            result.getViolations().addAll(sensitiveWordResult.getViolations());
            filteredContent = sensitiveWordResult.getFilteredContent();
            
            // 2. 检查个人信息
            FilterResult personalInfoResult = checkPersonalInfo(filteredContent);
            result.getWarnings().addAll(personalInfoResult.getWarnings());
            filteredContent = personalInfoResult.getFilteredContent();
            
            // 3. 检查恶意内容
            FilterResult maliciousResult = checkMaliciousContent(filteredContent);
            result.getViolations().addAll(maliciousResult.getViolations());
            
            // 4. 检查垃圾信息
            FilterResult spamResult = checkSpamContent(filteredContent);
            result.getWarnings().addAll(spamResult.getWarnings());
            
            // 5. 计算风险等级
            String riskLevel = calculateRiskLevel(result.getViolations(), result.getWarnings());
            result.setRiskLevel(riskLevel);
            
            // 6. 判断是否安全
            boolean isSafe = result.getViolations().isEmpty() && 
                           (!strictMode || result.getWarnings().isEmpty());
            result.setSafe(isSafe);
            result.setFilteredContent(filteredContent);
            
            // 7. 添加元数据
            result.getMetadata().put("userId", userId);
            result.getMetadata().put("originalLength", content.length());
            result.getMetadata().put("filteredLength", filteredContent.length());
            result.getMetadata().put("filterTime", System.currentTimeMillis());
            
            log.debug("Filtered user input for user: {}, safe: {}, risk: {}", 
                     userId, isSafe, riskLevel);
            
            return result;
        } catch (Exception e) {
            log.error("Error filtering user input for user: {}", userId, e);
            FilterResult result = new FilterResult();
            result.setSafe(false);
            result.setFilteredContent(content);
            result.setRiskLevel("HIGH");
            result.getViolations().add("FILTER_ERROR");
            return result;
        }
    }

    /**
     * 过滤AI输出内容
     */
    public FilterResult filterAIOutput(String content, String personaId) {
        if (!contentFilterEnabled) {
            FilterResult result = new FilterResult();
            result.setSafe(true);
            result.setFilteredContent(content);
            result.setRiskLevel("LOW");
            return result;
        }

        try {
            FilterResult result = new FilterResult();
            String filteredContent = content;
            
            // 1. 检查敏感词
            FilterResult sensitiveWordResult = checkSensitiveWords(filteredContent);
            result.getViolations().addAll(sensitiveWordResult.getViolations());
            filteredContent = sensitiveWordResult.getFilteredContent();
            
            // 2. 检查专业领域免责声明
            FilterResult disclaimerResult = checkProfessionalDisclaimer(filteredContent);
            result.getWarnings().addAll(disclaimerResult.getWarnings());
            filteredContent = disclaimerResult.getFilteredContent();
            
            // 3. 检查事实性声明
            FilterResult factualResult = checkFactualClaims(filteredContent);
            result.getWarnings().addAll(factualResult.getWarnings());
            
            // 4. 检查人格一致性
            FilterResult consistencyResult = checkPersonaConsistency(filteredContent, personaId);
            result.getWarnings().addAll(consistencyResult.getWarnings());
            
            // 5. 计算风险等级
            String riskLevel = calculateRiskLevel(result.getViolations(), result.getWarnings());
            result.setRiskLevel(riskLevel);
            
            // 6. 判断是否安全
            boolean isSafe = result.getViolations().isEmpty();
            result.setSafe(isSafe);
            result.setFilteredContent(filteredContent);
            
            // 7. 添加元数据
            result.getMetadata().put("personaId", personaId);
            result.getMetadata().put("originalLength", content.length());
            result.getMetadata().put("filteredLength", filteredContent.length());
            result.getMetadata().put("filterTime", System.currentTimeMillis());
            
            log.debug("Filtered AI output for persona: {}, safe: {}, risk: {}", 
                     personaId, isSafe, riskLevel);
            
            return result;
        } catch (Exception e) {
            log.error("Error filtering AI output for persona: {}", personaId, e);
            FilterResult result = new FilterResult();
            result.setSafe(false);
            result.setFilteredContent(content);
            result.setRiskLevel("HIGH");
            result.getViolations().add("FILTER_ERROR");
            return result;
        }
    }

    /**
     * 检查敏感词
     */
    private FilterResult checkSensitiveWords(String content) {
        FilterResult result = new FilterResult();
        String filteredContent = content;
        
        for (String sensitiveWord : SENSITIVE_WORDS) {
            if (content.toLowerCase().contains(sensitiveWord.toLowerCase())) {
                result.getViolations().add("SENSITIVE_WORD: " + sensitiveWord);
                
                if (autoReplace) {
                    String replacement = "*".repeat(sensitiveWord.length());
                    filteredContent = filteredContent.replaceAll(
                        "(?i)" + Pattern.quote(sensitiveWord), replacement);
                }
            }
        }
        
        result.setFilteredContent(filteredContent);
        return result;
    }

    /**
     * 检查个人信息
     */
    private FilterResult checkPersonalInfo(String content) {
        FilterResult result = new FilterResult();
        String filteredContent = content;
        
        // 检查手机号
        if (PHONE_PATTERN.matcher(content).find()) {
            result.getWarnings().add("PHONE_NUMBER_DETECTED");
            if (autoReplace) {
                filteredContent = PHONE_PATTERN.matcher(filteredContent)
                    .replaceAll("***-****-****");
            }
        }
        
        // 检查邮箱
        if (EMAIL_PATTERN.matcher(content).find()) {
            result.getWarnings().add("EMAIL_DETECTED");
            if (autoReplace) {
                filteredContent = EMAIL_PATTERN.matcher(filteredContent)
                    .replaceAll("***@***.***");
            }
        }
        
        // 检查身份证号
        if (ID_CARD_PATTERN.matcher(content).find()) {
            result.getWarnings().add("ID_CARD_DETECTED");
            if (autoReplace) {
                filteredContent = ID_CARD_PATTERN.matcher(filteredContent)
                    .replaceAll("****************");
            }
        }
        
        // 检查银行卡号
        if (BANK_CARD_PATTERN.matcher(content).find()) {
            result.getWarnings().add("BANK_CARD_DETECTED");
            if (autoReplace) {
                filteredContent = BANK_CARD_PATTERN.matcher(filteredContent)
                    .replaceAll("**** **** **** ****");
            }
        }
        
        result.setFilteredContent(filteredContent);
        return result;
    }

    /**
     * 检查恶意内容
     */
    private FilterResult checkMaliciousContent(String content) {
        FilterResult result = new FilterResult();
        
        // 检查恶意URL
        if (URL_PATTERN.matcher(content).find()) {
            // 这里可以集成URL安全检查服务
            result.getWarnings().add("URL_DETECTED");
        }
        
        // 检查SQL注入模式
        String[] sqlPatterns = {
            "(?i).*\\b(SELECT|INSERT|UPDATE|DELETE|DROP|CREATE|ALTER)\\b.*",
            "(?i).*\\b(UNION|OR|AND)\\s+\\d+\\s*=\\s*\\d+.*",
            "(?i).*'\\s*(OR|AND)\\s*'.*"
        };
        
        for (String pattern : sqlPatterns) {
            if (Pattern.matches(pattern, content)) {
                result.getViolations().add("SQL_INJECTION_ATTEMPT");
                break;
            }
        }
        
        // 检查XSS模式
        String[] xssPatterns = {
            "(?i).*<\\s*script.*",
            "(?i).*javascript\\s*:.*",
            "(?i).*on\\w+\\s*=.*"
        };
        
        for (String pattern : xssPatterns) {
            if (Pattern.matches(pattern, content)) {
                result.getViolations().add("XSS_ATTEMPT");
                break;
            }
        }
        
        result.setFilteredContent(content);
        return result;
    }

    /**
     * 检查垃圾信息
     */
    private FilterResult checkSpamContent(String content) {
        FilterResult result = new FilterResult();
        
        // 检查重复字符
        if (content.matches(".*([a-zA-Z0-9])\\1{5,}.*")) {
            result.getWarnings().add("REPEATED_CHARACTERS");
        }
        
        // 检查过多的大写字母
        long upperCaseCount = content.chars().filter(Character::isUpperCase).count();
        if (upperCaseCount > content.length() * 0.7 && content.length() > 10) {
            result.getWarnings().add("EXCESSIVE_CAPS");
        }
        
        // 检查过多的特殊字符
        long specialCharCount = content.chars()
            .filter(c -> !Character.isLetterOrDigit(c) && !Character.isWhitespace(c))
            .count();
        if (specialCharCount > content.length() * 0.3 && content.length() > 10) {
            result.getWarnings().add("EXCESSIVE_SPECIAL_CHARS");
        }
        
        result.setFilteredContent(content);
        return result;
    }

    /**
     * 检查专业领域免责声明
     */
    private FilterResult checkProfessionalDisclaimer(String content) {
        FilterResult result = new FilterResult();
        String filteredContent = content;
        
        // 检查医疗相关内容
        boolean hasMedicalContent = MEDICAL_KEYWORDS.stream()
            .anyMatch(keyword -> content.toLowerCase().contains(keyword.toLowerCase()));
        
        if (hasMedicalContent) {
            result.getWarnings().add("MEDICAL_CONTENT_DETECTED");
            if (autoReplace && !content.contains("医疗免责声明")) {
                filteredContent += "\n\n[医疗免责声明：以上内容仅供参考，不构成医疗建议。如有健康问题，请咨询专业医生。]"; 
            }
        }
        
        // 检查法律相关内容
        boolean hasLegalContent = LEGAL_KEYWORDS.stream()
            .anyMatch(keyword -> content.toLowerCase().contains(keyword.toLowerCase()));
        
        if (hasLegalContent) {
            result.getWarnings().add("LEGAL_CONTENT_DETECTED");
            if (autoReplace && !content.contains("法律免责声明")) {
                filteredContent += "\n\n[法律免责声明：以上内容仅供参考，不构成法律建议。如有法律问题，请咨询专业律师。]";
            }
        }
        
        // 检查金融相关内容
        boolean hasFinancialContent = FINANCIAL_KEYWORDS.stream()
            .anyMatch(keyword -> content.toLowerCase().contains(keyword.toLowerCase()));
        
        if (hasFinancialContent) {
            result.getWarnings().add("FINANCIAL_CONTENT_DETECTED");
            if (autoReplace && !content.contains("投资风险提示")) {
                filteredContent += "\n\n[投资风险提示：以上内容仅供参考，不构成投资建议。投资有风险，决策需谨慎。]";
            }
        }
        
        result.setFilteredContent(filteredContent);
        return result;
    }

    /**
     * 检查事实性声明
     */
    private FilterResult checkFactualClaims(String content) {
        FilterResult result = new FilterResult();
        
        // 检查绝对性声明
        String[] absolutePatterns = {
            "(?i).*\\b(一定|必须|绝对|肯定|100%|完全|永远|从不)\\b.*",
            "(?i).*\\b(always|never|definitely|absolutely|certainly)\\b.*"
        };
        
        for (String pattern : absolutePatterns) {
            if (Pattern.matches(pattern, content)) {
                result.getWarnings().add("ABSOLUTE_CLAIM_DETECTED");
                break;
            }
        }
        
        // 检查未经证实的数据
        if (content.matches(".*\\d+%.*") || content.matches(".*\\d+倍.*")) {
            result.getWarnings().add("STATISTICAL_CLAIM_DETECTED");
        }
        
        result.setFilteredContent(content);
        return result;
    }

    /**
     * 检查人格一致性
     */
    private FilterResult checkPersonaConsistency(String content, String personaId) {
        FilterResult result = new FilterResult();
        
        // 根据不同人格检查内容一致性
        switch (personaId) {
            case "sakura":
                // 小樱应该保持可爱、积极的语调
                if (content.matches(".*\\b(讨厌|烦人|愚蠢|笨蛋)\\b.*")) {
                    result.getWarnings().add("PERSONA_INCONSISTENCY: NEGATIVE_TONE");
                }
                break;
            case "doctor":
                // 医生人格应该保持专业、严谨
                if (!content.matches(".*\\b(建议|推荐|可能|或许|需要进一步)\\b.*") && 
                    MEDICAL_KEYWORDS.stream().anyMatch(keyword -> 
                        content.toLowerCase().contains(keyword.toLowerCase()))) {
                    result.getWarnings().add("PERSONA_INCONSISTENCY: UNPROFESSIONAL_TONE");
                }
                break;
            case "chef":
                // 厨师人格应该专注于烹饪相关内容
                if (!content.toLowerCase().matches(".*(食材|烹饪|料理|味道|口感).*") && 
                    content.length() > 50) {
                    result.getWarnings().add("PERSONA_INCONSISTENCY: OFF_TOPIC");
                }
                break;
        }
        
        result.setFilteredContent(content);
        return result;
    }

    /**
     * 计算风险等级
     */
    private String calculateRiskLevel(List<String> violations, List<String> warnings) {
        if (!violations.isEmpty()) {
            return "HIGH";
        } else if (warnings.size() >= 3) {
            return "MEDIUM";
        } else if (!warnings.isEmpty()) {
            return "LOW";
        } else {
            return "SAFE";
        }
    }

    /**
     * 批量过滤内容
     */
    public List<FilterResult> batchFilterContent(List<String> contents, String userId) {
        return contents.stream()
            .map(content -> filterUserInput(content, userId))
            .collect(Collectors.toList());
    }

    /**
     * 获取过滤统计信息
     */
    public Map<String, Object> getFilterStatistics() {
        Map<String, Object> stats = new HashMap<>();
        stats.put("filterEnabled", contentFilterEnabled);
        stats.put("strictMode", strictMode);
        stats.put("autoReplace", autoReplace);
        stats.put("sensitiveWordsCount", SENSITIVE_WORDS.size());
        stats.put("medicalKeywordsCount", MEDICAL_KEYWORDS.size());
        stats.put("legalKeywordsCount", LEGAL_KEYWORDS.size());
        stats.put("financialKeywordsCount", FINANCIAL_KEYWORDS.size());
        return stats;
    }

    /**
     * 更新敏感词库
     */
    public void updateSensitiveWords(Set<String> newWords) {
        SENSITIVE_WORDS.clear();
        SENSITIVE_WORDS.addAll(newWords);
        log.info("Updated sensitive words dictionary with {} words", newWords.size());
    }

    /**
     * 添加敏感词
     */
    public void addSensitiveWords(Set<String> words) {
        SENSITIVE_WORDS.addAll(words);
        log.info("Added {} sensitive words to dictionary", words.size());
    }

    /**
     * 移除敏感词
     */
    public void removeSensitiveWords(Set<String> words) {
        SENSITIVE_WORDS.removeAll(words);
        log.info("Removed {} sensitive words from dictionary", words.size());
    }
}